import FYGlobalVarMgr from "../Global/FYGlobalVarMgr";
import FYLog from "../Frame/FYLog";

/** 定时器管理器 */
export default class FYScheduleMgr {
    public static readonly Instance: FYScheduleMgr = new FYScheduleMgr();
    private constructor() { }
    /** 回调字典 */
    private _dictCB: { [key: string]: Function } = {}

    /**
     * 指定回调函数，调用对象等信息来添加一个新的定时器。
     * @param callback 回调
     * @param target 定时器添加的对象
     * @param interval 间隔时间
     * @param repeat 重复次数
     * @param delay 延迟时间
     */
    public schedule(callback: Function, target: cc.Node | cc.Component, interval: number, repeat: number, delay: number) {
        cc.director.getScheduler().enableForTarget(target);
        cc.director.getScheduler().schedule(callback, target, interval, repeat, delay, false);
    }

    /**
     * 指执行一次的定时器
     * @param callback 回调
     * @param target 定时器添加的对象
     * @param delay 延迟时间
     */
    public scheduleOnce(callback: Function, target: cc.Node | cc.Component, delay: number) {
        this.schedule(callback, target, 0, 0, delay);
    }

    /**
     * 取消定时器
     * @param callback 回调
     * @param target 定时器添加的对象
     */
    public unschedule(callback: Function, target: cc.Node | cc.Component) {
        cc.director.getScheduler().enableForTarget(target);
        cc.director.getScheduler().unschedule(callback, target);
    }

    /**
     * 取消所有定时器
     * @param target 定时器添加的对象
     */
    public unscheduleAllCallbacks(target: cc.Node | cc.Component) {
        cc.director.getScheduler().enableForTarget(target);
        cc.director.getScheduler().unscheduleAllForTarget(target);
    }

    /**
     * 调度器
     * @param callback 回调函数
     * @param ID 编号
     * @param interval 间隔时间
     * @param repeat 重复次数
     * @param delay 延迟时间
     * @param target 对象
     */
    public scheduleByID(callback: Function, ID: string, interval: number, repeat: number, delay: number, target: any = null) {
        if (target != null && target.uuid) {
            ID = ID + target.uuid;
        }
        if (this._dictCB[ID]) {
            // FYLog.warn("the ID in scheduleByID is exist");
        }
        let self = this;
        let cb = function () {
            // 这里不能直接移除 不然，如果想中途移除调度就移除不掉
            // delete self._dictCB[ID];
            if (callback) {
                callback();
            }
        }
        this._dictCB[ID] = cb;
        // 将ID注入对象中
        if (target) {
            if (!target._scheduleArrayID) {
                target._scheduleArrayID = [];
            }
            target._scheduleArrayID.push(ID);
        }
        cc.director.getScheduler().enableForTarget(target);
        cc.director.getScheduler().schedule(cb, FYGlobalVarMgr.Instance.Canvas, interval, repeat, delay, false);
    }

    /**
     * 只执行一次 调度器
     * @param callback 回调函数
     * @param ID 编号
     * @param delay 延迟时间
     * @param target 对象
     */
    public scheduleOnceByID(callback: Function, ID: string, delay: number, target: cc.Node | cc.Component = null) {
        if (target != null && target.uuid) {
            ID = ID + target.uuid;
        }
        if (this._dictCB[ID]) {
            // FYLog.warn("the ID in scheduleByID is exist");
        }
        let self = this;
        let cb = function () {
            delete self._dictCB[ID];
            if (callback) {
                // FYLog.log(ID)
                callback();
            }
        }
        this._dictCB[ID] = cb;
        // 将ID注入对象中
        if (target) {
            if (!target["_scheduleArrayID"]) {
                target["_scheduleArrayID"] = [];
            }
            target["_scheduleArrayID"].push(ID);
        }
        this.schedule(cb, FYGlobalVarMgr.Instance.Canvas, 0, 0, delay);
    }

    /**
     * 移除调度器
     * @param ID 编号
     * @param target 对象
     */
    public unscheduleByID(ID: string, target: cc.Node | cc.Component = null) {
        if (target != null && target.uuid) {
            ID = ID + target.uuid;
        }
        if (!this._dictCB[ID]) {
            // FYLog.warn("the ID is not find");
            return;
        }
        let cb = this._dictCB[ID];
        delete this._dictCB[ID];
        cc.director.getScheduler().enableForTarget(target);
        cc.director.getScheduler().unschedule(cb, FYGlobalVarMgr.Instance.Canvas);

    }

    /**
     * 移除对象的所有
     * @param target 对象
     */
    public unscheduleAllByTarget(target: cc.Node | cc.Component) {
        if (!target || !target["_scheduleArrayID"]) {
            return;
        }

        let scheduleArrayID = target["_scheduleArrayID"];
        for (let v of scheduleArrayID) {
            let cb = this._dictCB[v];
            if (cb) {
                delete this._dictCB[v];
                cc.director.getScheduler().enableForTarget(target);
                cc.director.getScheduler().unschedule(cb, FYGlobalVarMgr.Instance.Canvas);
            }
        }
    }

    /**
     * 是否包含关键字
     * @param key 关键字
     */
    public isContainerKey(key) {
        if (this._dictCB[key]) {
            return true;
        }
        return false;
    }
}
